import 'dart:ui';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

import 'editor/custom_editable_text.dart';

const CupertinoDynamicColor _kToolbarBorderColor =
    CupertinoDynamicColor.withBrightness(
  color: Color(0xFFB8B8B8),
  darkColor: Color(0xFF5B5B5B),
);
const CupertinoDynamicColor _kToolbarBackgroundColor =
    CupertinoDynamicColor.withBrightness(
  color: Color(0xB2FFFFFF),
  darkColor: Color(0xB2303030),
);
const double _kToolbarScreenPadding = 8.0;
const Radius _kToolbarBorderRadius = Radius.circular(8.0);
const EdgeInsets _kToolbarPadding = EdgeInsets.all(6.0);
const double _kToolbarWidth = 120.0;

/// 桌面输入框专用Toolbar
class ZzDesktopTextSelectionToolbar extends StatelessWidget {
  /// Creates a const instance of CupertinoTextSelectionToolbar.
  const ZzDesktopTextSelectionToolbar({
    super.key,
    required this.anchor,
    required this.children,
  }) : assert(children.length > 0);

  ZzDesktopTextSelectionToolbar.editableText({
    super.key,
    required BuildContext context,
    required MyEditableTextState editableTextState,
    bool showSelectionAll = true,
  })  : children = [
          ...editableTextState.contextMenuButtonItems
              .map((ContextMenuButtonItem buttonItem) {
            return ZzTextSelectionToolbarButton.iconText(
              context: context,
              onPressed: buttonItem.onPressed,
              text: AdaptiveTextSelectionToolbar.getButtonLabel(
                  context, buttonItem),
              icon: ZzTextSelectionToolbarButton.getButtonIcon(
                  context, buttonItem),
            );
          }),
          if (showSelectionAll &&
              editableTextState.textEditingValue.text.isNotEmpty &&
              editableTextState.contextMenuButtonItems.firstWhereOrNull(
                      (element) =>
                          element.type == ContextMenuButtonType.selectAll) ==
                  null)
            ZzTextSelectionToolbarButton.iconText(
              context: context,
              onPressed: () {
                editableTextState.selectAll(SelectionChangedCause.toolbar);
              },
              text: '全选',
              icon: Icons.select_all_outlined,
            ),
        ],
        anchor = editableTextState.contextMenuAnchors.primaryAnchor;


  ZzDesktopTextSelectionToolbar.editableTextNormal({
    super.key,
    required BuildContext context,
    required EditableTextState editableTextState,
    bool showSelectionAll = true,
  })  : children = [
    ...editableTextState.contextMenuButtonItems
        .map((ContextMenuButtonItem buttonItem) {
      return ZzTextSelectionToolbarButton.iconText(
        context: context,
        onPressed: buttonItem.onPressed,
        text: AdaptiveTextSelectionToolbar.getButtonLabel(
            context, buttonItem),
        icon: ZzTextSelectionToolbarButton.getButtonIcon(
            context, buttonItem),
      );
    }),
    if (showSelectionAll &&
        editableTextState.textEditingValue.text.isNotEmpty &&
        editableTextState.contextMenuButtonItems.firstWhereOrNull(
                (element) =>
            element.type == ContextMenuButtonType.selectAll) ==
            null)
      ZzTextSelectionToolbarButton.iconText(
        context: context,
        onPressed: () {
          editableTextState.selectAll(SelectionChangedCause.toolbar);
        },
        text: '全选',
        icon: Icons.select_all_outlined,
      ),
  ],
        anchor = editableTextState.contextMenuAnchors.primaryAnchor;

  /// Creates a 5x5 matrix that increases saturation when used with [ColorFilter.matrix].
  ///
  /// The numbers were taken from this comment:
  /// [Cupertino blurs should boost saturation](https://github.com/flutter/flutter/issues/29483#issuecomment-477334981).
  static List<double> _matrixWithSaturation(double saturation) {
    final double r = 0.213 * (1 - saturation);
    final double g = 0.715 * (1 - saturation);
    final double b = 0.072 * (1 - saturation);

    return <double>[
      r + saturation, g, b, 0, 0, //
      r, g + saturation, b, 0, 0, //
      r, g, b + saturation, 0, 0, //
      0, 0, 0, 1, 0, //
    ];
  }

  /// {@macro flutter.material.DesktopTextSelectionToolbar.anchor}
  final Offset anchor;

  /// {@macro flutter.material.TextSelectionToolbar.children}
  ///
  /// See also:
  ///   * [CupertinoDesktopTextSelectionToolbarButton], which builds a default
  ///     macOS-style text selection toolbar text button.
  final List<Widget> children;

  // Builds a toolbar just like the default Mac toolbar, with the right color
  // background, padding, and rounded corners.
  static Widget _defaultToolbarBuilder(BuildContext context, Widget child) {
    return Container(
      width: _kToolbarWidth,
      clipBehavior: Clip.hardEdge,
      decoration: const BoxDecoration(
        boxShadow: <BoxShadow>[
          BoxShadow(
            color: Color.fromARGB(60, 0, 0, 0),
            blurRadius: 10.0,
            spreadRadius: 0.5,
            offset: Offset(0.0, 4.0),
          ),
        ],
        borderRadius: BorderRadius.all(_kToolbarBorderRadius),
      ),
      child: BackdropFilter(
        // Flutter web doesn't support ImageFilter.compose on CanvasKit yet
        // (https://github.com/flutter/flutter/issues/120123).
        filter: ImageFilter.compose(
          outer: ColorFilter.matrix(
            _matrixWithSaturation(3),
          ),
          inner: ImageFilter.blur(
            sigmaX: 20,
            sigmaY: 20,
          ),
        ),
        child: DecoratedBox(
          decoration: BoxDecoration(
            color: _kToolbarBackgroundColor.resolveFrom(context),
            border: Border.all(
              color: _kToolbarBorderColor.resolveFrom(context),
            ),
            borderRadius: const BorderRadius.all(_kToolbarBorderRadius),
          ),
          child: Padding(
            padding: _kToolbarPadding,
            child: child,
          ),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    assert(debugCheckHasMediaQuery(context));

    final double paddingAbove =
        MediaQuery.paddingOf(context).top + _kToolbarScreenPadding;
    final Offset localAdjustment = Offset(_kToolbarScreenPadding, paddingAbove);

    return Padding(
      padding: EdgeInsets.fromLTRB(
        _kToolbarScreenPadding,
        paddingAbove,
        _kToolbarScreenPadding,
        _kToolbarScreenPadding,
      ),
      child: CustomSingleChildLayout(
        delegate: DesktopTextSelectionToolbarLayoutDelegate(
          anchor: anchor - localAdjustment,
        ),
        child: _defaultToolbarBuilder(
          context,
          Column(
            mainAxisSize: MainAxisSize.min,
            children: children,
          ),
        ),
      ),
    );
  }
}

/// A [TextButton] for the Material desktop text selection toolbar.
class ZzTextSelectionToolbarButton extends StatelessWidget {
  /// Creates an instance of DesktopTextSelectionToolbarButton.
  const ZzTextSelectionToolbarButton({
    super.key,
    required this.onPressed,
    required this.child,
  });

  static IconData getButtonIcon(
      BuildContext context, ContextMenuButtonItem buttonItem,
      {IconData custom = Icons.add_box_outlined}) {
    switch (Theme.of(context).platform) {
      case TargetPlatform.iOS:
      case TargetPlatform.macOS:
      case TargetPlatform.android:
      case TargetPlatform.fuchsia:
      case TargetPlatform.linux:
      case TargetPlatform.windows:
        assert(debugCheckHasMaterialLocalizations(context));
        switch (buttonItem.type) {
          case ContextMenuButtonType.cut:
            return Icons.cut_outlined;
          case ContextMenuButtonType.copy:
            return Icons.copy_outlined;
          case ContextMenuButtonType.paste:
            return Icons.paste_outlined;
          case ContextMenuButtonType.selectAll:
            return Icons.select_all_outlined;
          case ContextMenuButtonType.delete:
            return Icons.delete_outline;
          case ContextMenuButtonType.lookUp:
            return Icons.search_outlined;
          case ContextMenuButtonType.searchWeb:
            return Icons.search_outlined;
          case ContextMenuButtonType.share:
            return Icons.share_outlined;
          case ContextMenuButtonType.liveTextInput:
            return Icons.camera_alt_outlined;
          case ContextMenuButtonType.custom:
            return custom;
        }
    }
  }

  /// Create an instance of [DesktopTextSelectionToolbarButton] whose child is
  /// a [Text] widget in the style of the Material text selection toolbar.
  ZzTextSelectionToolbarButton.iconText({
    super.key,
    required BuildContext context,
    required this.onPressed,
    required IconData icon,
    required String text,
  }) : child = Row(
          children: [
            Icon(
              icon,
              size: 20,
            ),
            const SizedBox(
              width: 12,
            ),
            Text(
              text,
              overflow: TextOverflow.ellipsis,
              style: const TextStyle(
                inherit: false,
                fontSize: 14.0,
                letterSpacing: -0.15,
                fontWeight: FontWeight.w400,
              ).copyWith(
                color:
                    Theme.of(context).colorScheme.brightness == Brightness.dark
                        ? Colors.white
                        : Colors.black87,
              ),
            ),
          ],
        );

  /// {@macro flutter.material.TextSelectionToolbarTextButton.onPressed}
  final VoidCallback? onPressed;

  /// {@macro flutter.material.TextSelectionToolbarTextButton.child}
  final Widget child;

  @override
  Widget build(BuildContext context) {
    final ThemeData theme = Theme.of(context);
    final bool isDark = theme.colorScheme.brightness == Brightness.dark;
    final Color foregroundColor = isDark ? Colors.white : Colors.black87;

    return SizedBox(
      width: double.infinity,
      child: TextButton(
        style: TextButton.styleFrom(
          alignment: Alignment.centerLeft,
          enabledMouseCursor: SystemMouseCursors.basic,
          disabledMouseCursor: SystemMouseCursors.basic,
          foregroundColor: foregroundColor,
          shape: const RoundedRectangleBorder(),
          minimumSize: const Size(24.0, 44.0),
          padding: const EdgeInsets.fromLTRB(
            20.0,
            0.0,
            20.0,
            3.0,
          ),
        ),
        onPressed: onPressed,
        child: child,
      ),
    );
  }
}
